import requests
import time
import json
from quant.markets import OrderBook, MarketData, Functions
from quant.markets.functions import get_asset_value, get_contract_size
from quant.utils import logging, catch_exception, Timer2
from quant.accounts import Order
from quant.exchanges.basics import Socket, ChannelBasic, HandlerBasic, ApiBasic, SpiBasic
from quant.exchanges.util import AscendingChecker, int_prec_to_precision, spot_value_factor, simulate_deal_usdt_swap
# from quant.exchanges.gate_util import build_request
from quant.const import *


class GateSwapFunctions(Functions):
    def get_all_ticker(self):
        path = '/futures/usdt/tickers'
        url = rest_host + path

        response = self.session.get(url, timeout=3)
        if int(response.status_code) // 100 != 2:
            return {}
        j = response.json()

        result = {}
        _usdt = get_asset_value('usdt')
        for d in j:
            contract = d['contract']
            if not contract.endswith('_USDT'):
                continue

            symbol = resume_symbol(contract)
            result[symbol] = {
                'price': float(d['last']),
                'vol': float(d['volume_24h_quote']) * _usdt,
                'bid': None,
                'ask': None,
            }
        return result

    def get_all_contract_size(self):
        path = '/futures/usdt/contracts'
        url = rest_host + path

        response = self.session.get(url, timeout=3)
        if int(response.status_code) // 100 != 2:
            return {}
        j = response.json()

        result = {}
        for d in j:
            contract = d['name']
            if not contract.endswith('_USDT'):
                continue

            symbol = resume_symbol(contract)
            result[symbol] = float(d['quanto_multiplier'])
        return result

    def get_all_precision(self):
        path = '/futures/usdt/contracts'

        url = rest_host + path
        response = self.session.get(url, timeout=3)
        if int(response.status_code) // 100 != 2:
            return {}

        result = {}
        for d in response.json():
            contract = d['name']
            if not contract.endswith('_USDT'):
                continue

            symbol = resume_symbol(contract)
            price_unit = d['order_price_round']
            amount_unit = '1'

            result[symbol] = (price_unit, amount_unit)
        return result

    def get_recent_trade(self, symbol, limit=1000):
        path = '/futures/usdt/trades'
        url = '{}{}?contract={}&limit={}'.format(rest_host, path, format_symbol(symbol), limit)

        response = self.session.get(url, timeout=3)
        if int(response.status_code) // 100 != 2:
            return {}
        j = response.json()

        result = [
            (
                d['id'],
                'buy' if float(d['size']) > 0 else 'sell',
                float(d['price']),
                abs(float(d['size'])),
                float(d['create_time_ms']),
            )
            for d in j
        ]
        result.reverse()
        return result

    def get_value_factor(self, symbol):
        contract_size = get_contract_size(Exchange.Gate, symbol)
        asset_value = get_asset_value(symbol.split('/')[0])
        return contract_size * asset_value


def format_symbol(symbol):
    assert symbol.endswith('/usdt.swap')
    contract = symbol.split('.')[0]
    contract = contract.replace('/', '_').upper()
    return contract


def resume_symbol(contract):
    symbol = contract.replace('_', '/').lower() + '.swap'
    return symbol


rest_host = 'https://api.gateio.ws/api/v4'


if __name__ == '__main__':
    from quant.utils import set_test_mode
    set_test_mode()

    def try_function():
        fn = GateSwapFunctions()

        # a = fn.get_all_ticker()
        # a = [(s, dic) for s, dic in a.items()]
        # a.sort(key=lambda x: x[1]['vol'])
        # for i in a:
        #     print(i)

        a = fn.get_recent_trade('eth/usdt.swap', 1000)
        for i in a:
            print(i)
        print(len(a))

        # a = fn.get_all_contract_size()
        # for i in a.items():
        #     print(i)

        # a = fn.get_all_precision()
        # for i in a.items():
        #     print(i)

    try_function()
















